import React, { useRef, FC, useState, useEffect } from 'react'
import {
  Button,
  Form,
  Input,
  Modal,
  Row,
  Col,
  Select,
  Tag,
  message
} from 'antd'
import { useHistory } from 'react-router-dom'
import MyTable from '@/components/common/table'
import commom from '@/api'
import $axios from '@/utils/axios'
import formAxios from '@/utils/loginAxios'

const TaskList: FC = () => {
  const tableRef: RefType = useRef()
  const [jobGroupList, setJobGroupList] = useState([])
  const [jobGroupDefaultValue] = useState('-1')

  useEffect(() => {
    getJobGroupList()
  }, [])

  const getJobGroupList = async () => {
    const res = await $axios.get('/api/jobgroup/pageList?start=0&length=10000')
    const arr = []
    arr.push({
      label: '全部',
      value: '-1'
    })
    if (res?.data?.length > 0) {
      const jobGroupData = res.data

      for (let i = 0; i < jobGroupData.length; i += 1) {
        arr.push({
          label: jobGroupData[i].title,
          value: `${jobGroupData[i].id}`
        })
      }
    }
    setJobGroupList(arr)
  }

  // 新增任务按钮
  const AddBtn = () => (
    <Button className="fr" onClick={add} type="primary">
      新增任务
    </Button>
  )

  const glueTypeEnum = [
    { text: 'BEAN', value: 'BEAN' },
    { text: 'GLUE(Java)', value: 'GLUE_GROOVY' },
    { text: 'GLUE(Shell)', value: 'GLUE_SHELL' },
    { text: 'GLUE(Python)', value: 'GLUE_PYTHON' },
    { text: 'GLUE(PHP)', value: 'GLUE_PHP' },
    { text: 'GLUE(Nodejs)', value: 'GLUE_NODEJS' },
    { text: 'GLUE(PowerShell)', value: 'GLUE_POWERSHELL' }
  ]

  const findGlueTypeTitle = (glueType) => {
    let glueTypeTitle
    for (let i = 0; i < glueTypeEnum.length; i += 1) {
      if (glueType === glueTypeEnum[i].value) {
        glueTypeTitle = glueTypeEnum[i].text
      }
    }
    return glueTypeTitle
  }

  // 搜索栏配置项
  const searchConfigList = [
    {
      name: '执行器',
      key: 'jobGroup',
      width: '20%',
      textWrap: 'word-break',
      ellipsis: true,
      slot: (
        <Select
          options={jobGroupList}
          placeholder="请选择执行器"
          defaultValue={
            jobGroupList.length === 0 ? '-1' : jobGroupList[0].value
          }
          style={{ width: 250 }}
        />
      ),
      initialValue: jobGroupDefaultValue
    },
    {
      name: '任务状态',
      key: 'triggerStatus',
      width: 50,
      textWrap: 'word-break',
      ellipsis: true,
      slot: (
        <Select
          options={[
            { label: '全部', value: '-1' },
            { label: '停止', value: '0' },
            { label: '启动', value: '1' }
          ]}
          defaultValue="-1"
        />
      ),
      initialValue: '-1'
    },
    {
      key: 'jobDesc',
      slot: <Input placeholder="请输入任务描述" allowClear />,
      rules: [],
      initialValue: ''
    },
    {
      key: 'executorHandler',
      slot: <Input placeholder="请输入JobHandler" allowClear />,
      rules: [],
      initialValue: ''
    },
    {
      key: 'author',
      slot: <Input placeholder="请输入负责人" allowClear />,
      rules: [],
      initialValue: ''
    }
  ]
  const columns = [
    { title: '任务ID', dataIndex: 'id' },
    { title: '任务描述', dataIndex: 'jobDesc' },
    {
      title: '调度类型',
      dataIndex: 'scheduleType',
      render: (text, record) => {
        if (record.scheduleConf) {
          return `${record.scheduleType}：${record.scheduleConf}`
        }
        return record.scheduleType || record.jobCron
      }
    },
    {
      title: '运行模式',
      dataIndex: 'glueType',
      render: (text, record) => {
        const glueTypeTitle = findGlueTypeTitle(text)
        if (record.executorHandler) {
          return `${glueTypeTitle}：${record.executorHandler}`
        }
        return glueTypeTitle
      }
    },
    { title: '负责人', dataIndex: 'author' },
    {
      title: '状态',
      dataIndex: 'triggerStatus',
      render: (text) => {
        if (text === 1) {
          return <Button type="primary">RUNNING</Button>
        }
        return (
          <Button type="primary" danger>
            STOP
          </Button>
        )
      }
    },
    {
      title: '操作',
      dataIndex: 'operations',
      align: 'center',
      render: (text, record) => (
        <>
          <Button
            className="btn"
            onClick={() => runOnce(record.id)}
            size="small"
          >
            执行一次
          </Button>
          <Button
            className="btn"
            onClick={() => searchLog(record.id, record.jobGroup)}
            size="small"
          >
            查询日志
          </Button>
          <Button
            className="btn"
            onClick={() => viewMachines(record.jobGroup)}
            size="small"
          >
            注册节点
          </Button>
          {(record.scheduleType === 'CRON' ||
            record.scheduleType === 'FIX_RATE' ||
            record.jobCron !== '') && (
            <Button
              className="btn"
              onClick={() => nextRunTime(record.jobCron)}
              size="small"
            >
              下次执行时间
            </Button>
          )}

          <Button
            className="btn"
            onClick={() => runOrStop(record.triggerStatus === 1, record.id)}
            size="small"
          >
            {record.triggerStatus === 1 ? '停止' : '启动'}
          </Button>
          <Button
            className="btn"
            onClick={() => edit(record.id, record)}
            size="small"
          >
            编辑
          </Button>
          <Button
            className="btn"
            onClick={() => deleteTask(record.id)}
            size="small"
          >
            删除
          </Button>
          <Button className="btn" onClick={() => copy(record)} size="small">
            复制
          </Button>
        </>
      )
    }
  ]
  const runOnce = (id) => {
    const fieldsValue = runOnceForm.getFieldsValue(true)
    fieldsValue.id = `${id}`
    runOnceForm.setFieldsValue(fieldsValue)
    setRunOnceOpen(true)
  }

  const history = useHistory()
  const searchLog = (id, jobGroup) => {
    history.push({
      pathname: '/jobLogList',
      state: { taskId: `${id}`, group: `${jobGroup}` }
    })
  }

  const viewMachines = async (id) => {
    const params = new URLSearchParams()
    params.append('id', id || '')
    const res = await formAxios.post('/api/jobgroup/loadById', params)
    if (res?.data?.code === 200) {
      const { registryList } = res.data.content
      const items = registryList.map((item) => <Tag color="green">{item}</Tag>)
      Modal.info({
        title: '注册节点',
        content: <div>{items}</div>,
        onOk() {}
      })
    } else {
      message.error(res?.data?.msg || '查询注册节点异常')
    }
  }

  const nextRunTime = async (cron) => {
    const params = new URLSearchParams()
    params.append('cron', cron || '')
    const res = await formAxios.post('/api/jobinfo/nextTriggerTime', params)
    if (res?.data?.code === 200) {
      const times = res.data.content
      const items = times.map((item) => (
        <div>
          <Tag>{item}</Tag>
        </div>
      ))
      Modal.info({
        title: '下次执行时间',
        content: <div>{items}</div>,
        onOk() {}
      })
    } else {
      message.error(res?.data?.msg || '查询下次执行时间异常')
    }
  }

  const runOrStop = (curStatus, id) => {
    const tip = curStatus ? '停止' : '启动'
    Modal.info({
      title: '系统提示',
      content: `确认${tip}吗`,
      okText: '确定',
      onOk: async () => {
        const startOrStop = curStatus ? 'stop' : 'start'
        const params = new URLSearchParams()
        params.append('id', id || '')
        const res = await formAxios.post(`/api/jobinfo/${startOrStop}`, params)
        if (res?.data?.code === 200) {
          message.success(`${tip}任务成功！`)
          refreshTable()
        } else {
          message.error(`${tip}任务失败！`)
        }
      }
    })
  }

  // 刷新列表
  const refreshTable = () => {
    tableRef.current.update()
  }

  const deleteTask = (id) => {
    Modal.info({
      title: '删除任务',
      content: '确认删除吗',
      okText: '确定',
      onOk: async () => {
        const params = new URLSearchParams()
        params.append('id', id || '')
        const res = await formAxios.post('/api/jobinfo/remove', params)
        if (res?.data?.code === 200) {
          message.success('删除任务成功！')
          refreshTable()
        } else {
          message.error('删除任务失败！')
        }
      }
    })
  }

  const copy = (record) => {
    setTaskModalTitle('复制任务')
    setTaskFormOpen(true)
    setTaskId('')
    record.jobGroup = `${record.jobGroup}`
    record.addTime = ''
    record.updateTime = ''
    record.triggerStatus = '0'
    taskForm.setFieldsValue(record)
  }

  // 添加
  const add = () => {
    setTaskModalTitle('新增任务')
    setTaskFormOpen(true)
    setTaskId('')
  }

  const edit = (id, record) => {
    setTaskModalTitle('编辑任务')
    setTaskFormOpen(true)
    setTaskId(`${id}`)
    record.jobGroup = `${record.jobGroup}`
    taskForm.setFieldsValue(record)
  }

  const [runOnceOpen, setRunOnceOpen] = useState(false)
  const [runOnceConfirmLoading, setRunOnceConfirmLoading] = useState(false)

  // 确定执行一次
  const handleRunOnceOk = async () => {
    setRunOnceConfirmLoading(true)
    // 请求后台
    const runOnceParams = runOnceForm.getFieldsValue(true)
    const params = new URLSearchParams()
    params.append('id', runOnceParams.id || '')
    params.append('executorParam', runOnceParams.executorParam || '')
    params.append('addressList', runOnceParams.addressList || '')
    const res = await formAxios.post('/api/jobinfo/trigger', params)
    if (res.data.code === 200) {
      message.success('执行成功')
    } else {
      message.error('执行失败')
    }
    setRunOnceConfirmLoading(false)
    setRunOnceOpen(false)
    runOnceForm.setFieldsValue({})
  }

  const { TextArea } = Input

  const [runOnceForm] = Form.useForm()

  const [taskForm] = Form.useForm()

  const [taskModalTitle, setTaskModalTitle] = useState('')

  const [taskFormOpen, setTaskFormOpen] = useState(false)

  // 新增和复制时 为空 编辑时赋值
  const [taskId, setTaskId] = useState('')

  const handleSaveTask = async () => {
    const fieldsValue = taskForm.getFieldsValue(true)
    fieldsValue.id = taskId

    fieldsValue.misfireStrategy = 'DO_NOTHING'
    fieldsValue.scheduleType = 'CRON'
    fieldsValue.triggerStatus = ''
    fieldsValue.alarmEmail = ''
    fieldsValue.glueSource = ''
    fieldsValue.glueRemark = ''
    const keys = Object.keys(fieldsValue)
    const params = new URLSearchParams()
    // eslint-disable-next-line array-callback-return
    keys.map((item) => {
      if (
        item !== 'addTime' &&
        item !== 'updateTime' &&
        item !== 'triggerNextTime' &&
        item !== 'triggerLastTime' &&
        item !== 'triggerStatus' &&
        item !== 'glueUpdatetime'
      ) {
        const val = fieldsValue[item]
        if (item !== 'id') {
          params.append(item, val === null || val === 'null' ? '' : val)
        } else if (val !== '') {
          params.append(item, val)
        }
      }
    })
    const url = taskId === '' ? '/api/jobinfo/add' : '/api/jobinfo/update'
    const res = await formAxios.post(url, params)
    if (res?.data?.code === 200) {
      message.success('保存成功')
      taskForm.setFieldsValue({})
      setTaskFormOpen(false)
      refreshTable()
    } else {
      message.error(res?.data?.msg || '保存失败')
    }
  }

  return (
    <>
      <AddBtn />
      <MyTable
        apiFun={commom.getTaskList}
        columns={columns}
        ref={tableRef}
        searchConfigList={searchConfigList}
      />
      <Modal
        title="执行一次"
        visible={runOnceOpen}
        onOk={handleRunOnceOk}
        confirmLoading={runOnceConfirmLoading}
        onCancel={() => {
          setRunOnceOpen(false)
        }}
      >
        <Form name="basic" wrapperCol={{ span: 16 }} form={runOnceForm}>
          <Form.Item
            label="任务参数"
            name="executorParam"
            rules={[{ message: '请输入任务参数!' }]}
          >
            <TextArea rows={2} />
          </Form.Item>

          <Form.Item
            label="机器地址"
            name="addressList"
            rules={[
              { message: '请输入本次执行的机器地址，为空则从执行器获取!' }
            ]}
          >
            <TextArea rows={2} />
          </Form.Item>
          <Form.Item style={{ display: 'none' }} name="id">
            <Input />
          </Form.Item>
        </Form>
      </Modal>
      <Modal
        title={taskModalTitle}
        visible={taskFormOpen}
        onOk={handleSaveTask}
        onCancel={() => {
          setTaskFormOpen(false)
          // 清空表单
          taskForm.setFieldsValue({})
        }}
        width={1000}
      >
        <Form
          name="task"
          wrapperCol={{ span: 16 }}
          labelCol={{ span: 6 }}
          form={taskForm}
          labelAlign="left"
        >
          <Row>
            <Col span={12}>
              <Form.Item
                label="执行器"
                name="jobGroup"
                rules={[{ required: true, message: '请选择执行器!' }]}
                initialValue={
                  jobGroupList.filter((a) => a.label !== '全部').length === 0
                    ? ''
                    : jobGroupList.filter((a) => a.label !== '全部')[0].value
                }
              >
                <Select
                  options={jobGroupList.filter((a) => a.label !== '全部')}
                  defaultValue={
                    jobGroupList.filter((a) => a.label !== '全部').length === 0
                      ? ''
                      : jobGroupList.filter((a) => a.label !== '全部')[0].value
                  }
                />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item
                label="任务描述"
                name="jobDesc"
                rules={[{ required: true, message: '请输入任务描述!' }]}
              >
                <Input placeholder="请输入任务描述" />
              </Form.Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Form.Item
                label="路由策略"
                name="executorRouteStrategy"
                rules={[{ required: true, message: '请输入路由策略!' }]}
                initialValue="FIRST"
              >
                <Select
                  options={[
                    { label: '第一个', value: 'FIRST' },
                    { label: '最后一个', value: 'LAST' },
                    { label: '轮询', value: 'ROUND' },
                    { label: '随机', value: 'RANDOM' },
                    { label: '一致性HASH', value: 'CONSISTENT_HASH' },
                    { label: '最不经常使用', value: 'LEAST_FREQUENTLY_USED' },
                    { label: '最近最久未使用', value: 'LEAST_RECENTLY_USED' },
                    { label: '故障转移', value: 'FAILOVER' },
                    { label: '忙碌转移', value: 'BUSYOVER' },
                    { label: '分片广播', value: 'SHARDING_BROADCAST' }
                  ]}
                  defaultValue="FIRST"
                />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item
                label="Cron"
                name="scheduleConf"
                rules={[{ required: true, message: '请输入Cron表达式!' }]}
              >
                <Input placeholder="cron表达式" />
              </Form.Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Form.Item label="运行模式" name="glueType" initialValue="BEAN">
                <Select
                  options={[
                    { label: 'BEAN', value: 'BEAN' },
                    { label: 'GLUE(Java)', value: 'GLUE_GROOVY' },
                    { label: 'GLUE(Shell)', value: 'GLUE_SHELL' },
                    { label: 'GLUE(Python)', value: 'GLUE_PYTHON' },
                    { label: 'GLUE(PHP)', value: 'GLUE_PHP' },
                    { label: 'GLUE(Nodejs)', value: 'GLUE_NODEJS' },
                    { label: 'GLUE(PowerShell)', value: 'GLUE_POWERSHELL' }
                  ]}
                  defaultValue="BEAN"
                />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item
                label="JobHandler"
                name="executorHandler"
                rules={[{ required: true, message: '请输入JobHandler!' }]}
              >
                <Input placeholder="请输入JobHandler" />
              </Form.Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Form.Item
                label="阻塞处理策略"
                name="executorBlockStrategy"
                rules={[{ required: true, message: '请选择阻塞处理策略!' }]}
                initialValue="SERIAL_EXECUTION"
              >
                <Select
                  options={[
                    { label: '单机串行', value: 'SERIAL_EXECUTION' },
                    { label: '丢弃后续调度', value: 'DISCARD_LATER' },
                    { label: '覆盖之前调度', value: 'COVER_EARLY' }
                  ]}
                  defaultValue="SERIAL_EXECUTION"
                />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="子任务ID" name="childJobId">
                <Input placeholder="请输入子任务的任务ID,如存在多个则逗号隔开" />
              </Form.Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Form.Item label="任务超时时间" name="executorTimeout">
                <Input placeholder="任务超时时间，单位秒，大于零时生效" />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="失败重试次数" name="executorFailRetryCount">
                <Input placeholder="失败重试次数，大于零时生效" />
              </Form.Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Form.Item
                label="负责人"
                name="author"
                rules={[{ required: true, message: '请输入负责人!' }]}
              >
                <Input placeholder="请输入负责人" />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item
                label="日期类型"
                name="dateType"
                rules={[{ required: true, message: '请选择日期类型!' }]}
                initialValue="0"
              >
                <Select
                  options={[
                    { label: '全部', value: '0' },
                    { label: '非交易日', value: '1' },
                    { label: '交易日', value: '2' }
                  ]}
                  defaultValue="0"
                />
              </Form.Item>
            </Col>
          </Row>
          <Row>
            <Col span={24}>
              <Form.Item
                label="任务参数"
                name="executorParam"
                labelAlign="left"
                labelCol={{ span: 3 }}
                wrapperCol={{ span: 20 }}
              >
                <TextArea rows={4} placeholder="请输入任务参数" />
              </Form.Item>
            </Col>
          </Row>
        </Form>
      </Modal>
    </>
  )
}
export default TaskList
